package com.sxf.auth.captcha.service;

import com.sxf.auth.captcha.vo.VerifyImageVO;
import com.sxf.cache.CacheUtil;
import com.sxf.cache.EhcacheElementType;
import com.sxf.common.exceptions.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import com.sxf.auth.captcha.VerifyImageHelper;
import com.sxf.auth.captcha.enums.CaptchaErrorEnum;
import com.sxf.redis.RedisClient;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.UUID;

/**
 * @author: SSLi
 * @description
 * @date: 2020/4/15 8:58
 */
@Service
public class ImageVerifyCodeService {

//    @Autowired
//    private RedisClient redisClient;

    @Value("${verifyCode.imageVerifyCodeExpireTime:60}")
    private Long imageVerifyCodeExpireTime;

    @Value("${verifyCode.allowance:10}")
    private int allowance;

    private static final String IMG_PATH = "classpath:static/imageVerify";

    private static final String PREFIX = "ImageVerifyCode-X-";

    private static final String TEMP_IMG_PATH = "classpath:static/template/template.png";

    private static final String UNDER_IMG_PATH = "classpath:static/template/under.png";


    private static final Logger logger = LoggerFactory.getLogger(ImageVerifyCodeService.class);

    @Autowired
    CacheUtil cacheUtil;
    /**
     * @return BaseRestResult 返回类型
     * @description 生成滑块拼图验证码
     */

    public VerifyImageVO getImageVerifyCode() {
        //读取图库目录
        VerifyImageVO verifyImageVO = new VerifyImageVO();
        try {
            File imgCatalog = getFile(IMG_PATH);
            File[] files = imgCatalog.listFiles();
            Optional.ofNullable(files).orElseThrow();
            int randNum = new Random().nextInt(files.length);
            File targetFile = files[randNum];
            File tempImgFile = getFile(TEMP_IMG_PATH);
            File underFile = getFile(UNDER_IMG_PATH);
            //根据模板裁剪图片
            Map<String, Object> resultMap = VerifyImageHelper.generateImage(tempImgFile, targetFile, underFile);
            int xWidth = (int) resultMap.get("X");
            //存入redis
            String uuid = UUID.randomUUID().toString();
            cacheUtil.set(EhcacheElementType.CAPTCHA,PREFIX + uuid, xWidth);
            resultMap.put("key", PREFIX + uuid);
            //移除map的滑动距离，不返回给前端
            resultMap.remove("X");

            logger.info("key=" + PREFIX + uuid);
            logger.info("X=" + xWidth);
            
            verifyImageVO.setCutImage((String) resultMap.get("cutImage"));
            verifyImageVO.setBackImage((String) resultMap.get("backImage"));
            verifyImageVO.setKey((String) resultMap.get("key"));
            verifyImageVO.setYNumber((int)resultMap.get("Y"));
            verifyImageVO.setYPercent(String.valueOf(resultMap.get("yPercent")));

        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            throw new BusinessException(CaptchaErrorEnum.VERIFY_CODE_SEND_FAIL);
        }
        return verifyImageVO;
    }


    /**
     * 校验滑块拼图验证码
     *
     * @param moveLength 移动距离
     * @param key 验证图片键
     * @param needDel 认证后是否需要删除
     * @description 生成图形验证码
     */

    public void verifyImageCode(Integer moveLength,String key, Boolean needDel) {
        try {
            Object xWidth = cacheUtil.get(EhcacheElementType.CAPTCHA,key);
            Optional.ofNullable(xWidth).orElseThrow(() -> new BusinessException(CaptchaErrorEnum.IMAGE_EXPIRES));
            if (Math.abs((int) xWidth - moveLength) > allowance) {
                cacheUtil.delete(EhcacheElementType.CAPTCHA,key);
                throw new BusinessException(CaptchaErrorEnum.IMAGE_VERIFY_FAIL);
            }
        } finally {
            if (needDel != null && needDel) {
                cacheUtil.delete(EhcacheElementType.CAPTCHA,key);
            }
        }
    }


    private File getFile(String path) throws FileNotFoundException {
        String staticPath = System.getProperty("staticPath");
        if(StringUtils.isEmpty(staticPath)){
            return ResourceUtils.getFile(path);
        }
        String realPath = staticPath + path.replaceAll("classpath:", "/");
        System.out.println(realPath);
        return new File(realPath);
    }

}
